package cn.virens.common.project.base.utils;


import cn.virens.common.util.core.stream.StreamUtil;
import cn.virens.common.util.exception.APIException;

import java.io.Serializable;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.function.Function;

public class MapSearchUtil {

    /**
     * 在Map中查找权重最高的一条数据(返回KEY)
     */
    public static String searchKey(Map<String, String> map, Function<Entry<String, String>, Double> function) {
        return search(map, function).map(Item::getKey).orElse(null);
    }

    /**
     * 在Map中查找权重最高的一条数据(返回VALUE)
     */
    public static String searchValue(Map<String, String> map, Function<Entry<String, String>, Double> function) {
        return search(map, function).map(Item::getValue).orElse(null);
    }

    /**
     * 在Map中查找权重最高的一条数据
     */
    private static Optional<Item> search(Map<String, String> map, Function<Entry<String, String>, Double> function) {
        return Optional.ofNullable(map).flatMap(m -> StreamUtil.stream(m.entrySet()).map(e -> {
            return new Item(function.apply(e), e.getValue(), e.getKey());
        }).max((a, b) -> a.compare(b)));
    }

    @SuppressWarnings("serial")
    private static class Item implements Serializable {
        private double similar;
        private String value;
        private String key;

        private Item(Double similar, String value, String key) {
            this.similar = similar == null ? 0 : similar;
            this.value = value;
            this.key = key;
        }

        public int compare(Item other) throws APIException {
            return Double.compare(similar, other.similar);
        }

        public String getValue() {
            return value;
        }

        public String getKey() {
            return key;
        }

    }
}
